use crate::convert::{IntoResponse, FromBody};
use crate::http::HttpContentType;
use serde::ser::Serialize;
use serde::de::DeserializeOwned;

pub struct Json<T>(pub T);

impl<T: Serialize> IntoResponse for Json<T> {
    fn status_code(&self) -> u16 {
        200 
    }

    fn content_type(&self) -> HttpContentType {
        HttpContentType::ApplicationJson
    }

    fn into_body(self) -> Vec<u8> {
        let json = serde_json::to_string(&self.0).unwrap();
        json.into_bytes()
    }
}

impl<T: DeserializeOwned> FromBody for Json<T> {
    type Err = serde_json::Error;
    fn from_body(bytes: Vec<u8>) -> Result<Self, Self::Err> {
        let val  = serde_json::from_slice::<T>(&bytes)?;
        Ok(Json(val))
    }
}